//
// Created by HZH on 2023-04-28.
//

#ifndef TEST_BZDB_H
#define TEST_BZDB_H

#include "string.h"

// 最多多少行
#define BzDB_MAX_ROW_COUNT 100
// 最多多少列
#define BzDB_MAX_COL_COUNT 10
// 字符串的最大长度
#define BzDB_STRING_MAXLEN 255

typedef enum {
    STRING,
    INTEGER
}BzDB_ValueType;

typedef struct BzDB_String{
    char data[BzDB_STRING_MAXLEN];
}BzDB_String_t;


typedef struct BzDB_Integer{
    int data;
}BzDB_Integer_t;


typedef struct BzDB_Value_t{
    BzDB_Integer_t valueint;
    BzDB_String_t valuestring ;
}BzDB_Value_t;

typedef struct BzDB_Row_t{
    // 一行里面最多MAX_COL_COUNT个数
    BzDB_Value_t value[BzDB_MAX_COL_COUNT];
}BzDB_Row_t;

typedef struct BzDB_Table_t{
    // 存放列名
    BzDB_String_t col_names[BzDB_MAX_COL_COUNT];
    BzDB_ValueType col_names_type[BzDB_MAX_COL_COUNT];

    // 存放行名
    BzDB_Row_t row_list[BzDB_MAX_ROW_COUNT];

    int used_row_count ;
    int used_col_count ;
    int max_row_count  ;
    int max_col_count  ;
}BzDB_Table_t;

// ===========================================

typedef struct BzDB_Select_Condition_t{
    BzDB_ValueType value_type;
    const char col_name[BzDB_STRING_MAXLEN];
    const char op[BzDB_STRING_MAXLEN];
    int value_int;
    const char value_string[BzDB_STRING_MAXLEN];
}BzDB_Select_Condition_t;



#ifdef __cplusplus
extern "C"{
#endif

//// 判断某一行是否满足条件
//int BzDB_private_isOneRow_string_OK(BzDB_Table_t * dbTable,int row_index , const char * col_name , const char* op ,const char * value );
//int BzDB_private_isOneRow_integer_OK(BzDB_Table_t * dbTable,int row_index , const char * col_name , const char * op , int value );
//// 打印一行数据
//void BzDB_private_printOneRow(BzDB_Table_t * dbTable,int row_index);
#ifdef __cplusplus
};
#endif

#ifdef __cplusplus
extern "C"{
#endif

// =====================================
/**
 * @desc
 * @param bz_str
 * @param msg
 */
void BzDB_String_set(BzDB_String_t* bz_str , const char * msg);
void BzDB_Integer_set(BzDB_Integer_t *bz_int , int value);
const char * BzDB_Value_get_string(BzDB_Value_t *value);
int BzDB_Value_get_integer(BzDB_Value_t *value);
void BzDB_Value_set_string(BzDB_Value_t *value , const char * msg);
void BzDB_Value_set_integer(BzDB_Value_t *value , int valueint);

// =========================================================
int BzDB_find_col_name_index(BzDB_Table_t * dbTable , const char* row_name);
int BzDB_Row_t_get_by_col_name(BzDB_Table_t * table ,BzDB_Row_t *row , const char * col_name,BzDB_Value_t *value);
// ========================================================

void BzDB_Table_t_init(BzDB_Table_t * dbTable ,int col_num , const char* col_name_list[] ,BzDB_ValueType col_name_type_list[] );
void BzDB_insert(BzDB_Table_t * dbTable , void * row_value[]);
void BzDB_delete(BzDB_Table_t * dbTable);


void BzDB_select_index_by_Row_t(BzDB_Table_t * dbTable, BzDB_Row_t selected_rows[] , int row_len , int index_list[],int* index_list_len);

void BzDB_showAll(BzDB_Table_t * dbTable);

// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ select ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
void BzDB_select_by_string(BzDB_Table_t * dbTable,const char* col_name ,const char* op, const char* value , BzDB_Row_t res[],int *res_count);
void BzDB_select_by_integer(BzDB_Table_t * dbTable,const char* col_name , const char* op , int value,BzDB_Row_t res[],int *res_count);
void BzDB_select_by_integer_between(BzDB_Table_t * dbTable,
                                    const char* col_name ,
                                    int min_value,
                                    int max_value,
                                    BzDB_Row_t res[],
                                    int *res_count);

void BzDB_select_by_multiple_condition(BzDB_Table_t * dbTable ,
                                       BzDB_Select_Condition_t condition_list[],
                                       int condition_list_len ,
                                       BzDB_Row_t res[],
                                       int *res_count,
                                       const char* connect_type
);

void BzDB_Row_Intersection(BzDB_Row_t rows1[], int rows1_len , BzDB_Row_t rows2[], int rows2_len , BzDB_Row_t res_rows[] , int* res_rows_len);
void BzDB_Row_Union(BzDB_Row_t rows1[], int rows1_len , BzDB_Row_t rows2[], int rows2_len , BzDB_Row_t res_rows[] , int* res_rows_len);
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ select ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

// ======= 删除 ===============================================
void BzDB_delete_by_index(BzDB_Table_t * dbTable , int index_list[] , int index_list_len);

// ====== 更新 ===========================================
void BzDB_update_by_index_list(BzDB_Table_t *dbTable , int index_list[],int index_list_len,const char* col_name,void * value);
void BzDB_update_by_index_list_user_op(BzDB_Table_t *dbTable , int index_list[],int index_list_len,const char* col_name,void* value_in,void (*user_op)(BzDB_Value_t *v_bz,void * value_in));

void BzDB_code_demo_save();
void BzDB_code_demo_read();

void BzDB_create_table_from_txt(BzDB_Table_t *table,const char* file_path);
void BzDB_save_table_to_txt(BzDB_Table_t *table,const char* file_path);
void BzDB_create_table_from_json(BzDB_Table_t *table,const char* file_path);
#ifdef __cplusplus
};
#endif

#endif //TEST_BZDB_H
